package com.gitee.zhziyun.cnfsystem.ui.component;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.gitee.zhziyun.cnfsystem.config.AvatarConfig;
import com.gitee.zhziyun.cnfsystem.master.AppMaster;
import com.gitee.zhziyun.cnfsystem.model.FileAccept;
import com.gitee.zhziyun.cnfsystem.model.FileSource;
import com.gitee.zhziyun.cnfsystem.model.UserInfo;
import com.gitee.zhziyun.cnfsystem.ui.ChatManagerUI;
import com.gitee.zhziyun.cnfsystem.ui.ChatUI;

import javax.swing.*;
import javax.swing.border.Border;
import javax.swing.border.CompoundBorder;
import javax.swing.border.EmptyBorder;
import javax.swing.border.MatteBorder;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;

public class UserListPane extends JScrollPane {
    private final JList<UserEntry> userList;
    private final DefaultListModel<UserEntry> listModel;
    private final Map<String, UserInfo> ipUserMap;
    private final AppMaster appMaster;
    private int hoverIndex = -1; // 跟踪鼠标悬停的索引

    private final Map<String, ChatUI> ipChatMap = new HashMap<>();

    // 内部类存储IP和UserInfo的组合
    private record UserEntry(String ip, UserInfo userInfo) {
    }

    public UserListPane(AppMaster appMaster) {
        this.appMaster = appMaster;
        this.ipUserMap = appMaster.getIpUserMap();
        // 创建列表模型和数据
        listModel = new DefaultListModel<>();
        updateListModel();

        // 创建列表并配置
        userList = new JList<>(listModel);
        userList.setCellRenderer(new UserListRenderer());
        userList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
        userList.setFixedCellHeight(50); // 固定行高
        userList.setBackground(Color.WHITE);

        // 添加鼠标事件监听
        userList.addMouseListener(new UserListMouseListener());
        userList.addMouseMotionListener(new UserListMouseListener()); // 添加鼠标移动监听

        // 设置滚动面板
        this.setViewportView(userList);
        this.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);

        // 每3秒更新列表
        new Timer(3000, e -> updateListModel()).start();

        appMaster.addUserStatusListener(
                new AppMaster.UserStatusListener() {
                    @Override
                    public void userOnline(String ip, UserInfo userInfo) {
                        listModel.addElement(new UserEntry(ip, userInfo));
                    }

                    @Override
                    public void userOffline(String ip) {
                        for (int i = 0; i < listModel.getSize(); i++) {
                            UserEntry entry = listModel.getElementAt(i);
                            if (entry.ip.equals(ip)) {
                                listModel.removeElementAt(i);
                                break;
                            }
                        }
                    }
                }
        );

        // 创建接收消息的监听器
        appMaster.addMessageListener(new AppMaster.MessageListener() {
            @Override
            public void onMessage(String ip, String message) {
                if (!ipChatMap.containsKey(ip) && !"用户已关闭窗口".equals(message))  {
                    ipChatMap.put(ip, new ChatUI(appMaster, ip, ipUserMap.get(ip).getReceivePort(), new ChatUI.CloseWindow() {
                        @Override
                        public void onCloseWindow() {
                            ipChatMap.remove(ip);
                            try {
                                appMaster.sendMessageToUser("用户已关闭窗口", ip, ipUserMap.get(ip).getReceivePort());
                            } catch (JsonProcessingException ex) {
                                throw new RuntimeException(ex);
                            }
                        }
                    }));
                }

                if(ipChatMap.containsKey(ip)) {
                    ipChatMap.get(ip).setExtendedState(JFrame.NORMAL);                // 恢复窗口状态
                    ipChatMap.get(ip).toFront();                                      // 将窗口置于最前
                    ipChatMap.get(ip).addTextMessage(ip, message, false);  // 添加参数：标识对方发送的消息
                }

            }
            @Override
            public void onFileMessage(String ip, FileSource fileSource) {
                if(!ipChatMap.containsKey(ip)) {
                    ipChatMap.put(ip, new ChatUI(appMaster, ip, ipUserMap.get(ip).getReceivePort(), new ChatUI.CloseWindow() {
                        @Override
                        public void onCloseWindow() {
                            ipChatMap.remove(ip);
                            try {
                                appMaster.sendMessageToUser("用户已关闭窗口", ip, ipUserMap.get(ip).getReceivePort());
                            } catch (JsonProcessingException ex) {
                                throw new RuntimeException(ex);
                            }
                        }
                    }));
                }

                ipChatMap.get(ip).setExtendedState(JFrame.NORMAL);          // 恢复窗口状态
                ipChatMap.get(ip).toFront();                                // 将窗口置于最前
                ipChatMap.get(ip).addFileReceiveMessage(ip, fileSource, false);
            }

            @Override
            public void onFileAccept(String ip, FileAccept fileAccept) {
                ipChatMap.get(ip).getFileSenderMap().get(fileAccept.getUUID()).start(ip, fileAccept.getPort());
            }
        });
    }

    // 更新列表模型数据
    private void updateListModel() {
        listModel.clear();
        for (Map.Entry<String, UserInfo> entry : ipUserMap.entrySet()) {
            listModel.addElement(new UserEntry(entry.getKey(), entry.getValue()));
        }
    }

    // 自定义渲染器
    private class UserListRenderer extends JPanel implements ListCellRenderer<UserEntry> {
        private final JLabel avatarLabel = new JLabel();
        private final JLabel nameLabel = new JLabel();
        private final JLabel addrLabel = new JLabel();

        public UserListRenderer() {
            setLayout(new FlowLayout(FlowLayout.LEFT));
            setOpaque(true);

            // 设置头像标签
            avatarLabel.setPreferredSize(new Dimension(40, 40));
            avatarLabel.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 10));

            // 创建信息面板
            JPanel infoPanel = new JPanel(new GridLayout(2, 1));
            infoPanel.setOpaque(false);
            nameLabel.setFont(new Font("宋体", Font.PLAIN, 14));
            addrLabel.setFont(new Font("宋体", Font.PLAIN, 12));
            infoPanel.add(nameLabel);
            infoPanel.add(addrLabel);

            add(avatarLabel);
            add(infoPanel);
        }

        @Override
        public Component getListCellRendererComponent(
                JList<? extends UserEntry> list,
                UserEntry entry,
                int index,
                boolean isSelected,
                boolean cellHasFocus) {

            // 设置用户信息
            UserInfo userInfo = entry.userInfo;
            nameLabel.setText(userInfo.getUserName());
            addrLabel.setText(userInfo.getHostName() + " " + entry.ip + ":" + userInfo.getReceivePort());
            avatarLabel.setIcon(getAvatarIcon(userInfo.getAvatarId()));

            // 设置背景和边框
            if (index == hoverIndex) {
                setBackground(new Color(230, 240, 255)); // 悬停状态
            } else {
                setBackground(Color.WHITE);                       // 默认状态
            }

            // 底部边框
            Border lineBorder = new MatteBorder(0, 0, 1, 0, Color.LIGHT_GRAY);
            Border emptyBorder = new EmptyBorder(0, 0, 0, 0);
            setBorder(new CompoundBorder(lineBorder, emptyBorder));

            return this;
        }

        private ImageIcon getAvatarIcon(int avatarId) {
            ImageIcon originalIcon = new ImageIcon(Objects.requireNonNull(
                    ChatManagerUI.class.getResource(AvatarConfig.getPathById(avatarId))));
            Image scaledImg = originalIcon.getImage().getScaledInstance(40, 40, Image.SCALE_SMOOTH);
            return new ImageIcon(scaledImg);
        }
    }

    // 鼠标事件监听器
    private class UserListMouseListener extends MouseAdapter {
        @Override
        public void mouseClicked(MouseEvent e) {
            // 只有当点击在有效项目上时才处理
            int index = userList.locationToIndex(e.getPoint());
            if (index != -1) {
                Rectangle cellBounds = userList.getCellBounds(index, index);
                if (cellBounds != null && cellBounds.contains(e.getPoint())) {
                    UserEntry entry = listModel.get(index);

                    if (!ipChatMap.containsKey(entry.ip)) {
                        ipChatMap.put(entry.ip,
                                new ChatUI(
                                    appMaster, entry.ip,
                                    entry.userInfo.getReceivePort(),
                                    () -> {
                                        ipChatMap.remove(entry.ip);
                                        try {
                                            appMaster.sendMessageToUser("用户已关闭窗口", entry.ip, entry.userInfo.getReceivePort());
                                        } catch (JsonProcessingException ex) {
                                            throw new RuntimeException(ex);
                                        }
                                    }
                        ));
                    } else {
                        ipChatMap.get(entry.ip).setExtendedState(JFrame.NORMAL); // 恢复窗口状态
                        ipChatMap.get(entry.ip).toFront();                      // 将窗口置于最前
                    }


                }
            }
        }

        @Override
        public void mouseMoved(MouseEvent e) {
            int index = userList.locationToIndex(e.getPoint());
            if (index != -1) {
                // 精确检查鼠标是否在列表项范围内
                Rectangle cellBounds = userList.getCellBounds(index, index);
                if (cellBounds != null && cellBounds.contains(e.getPoint())) {
                    // 在有效范围内
                    if (hoverIndex != index) {
                        hoverIndex = index;
                        userList.repaint();
                    }
                    return;
                }
            }

            // 不在任何列表项上
            if (hoverIndex != -1) {
                hoverIndex = -1;
                userList.repaint();
            }
        }

        @Override
        public void mouseExited(MouseEvent e) {
            // 清除悬停状态
            if (hoverIndex != -1) {
                hoverIndex = -1;
                userList.repaint();
            }
        }
    }
}

